<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'

const props = defineProps({
  modelValue: String,
  type: {
    type: String,
    default: 'text',
  },
  placeholder: {
    type: String,
    default: '',
  },
  maxlength: {
    type: [Number, String],
    default: 22,
  },
  isShowPass: {
    type: [Boolean, String],
    default: false,
  },
  isShowCode: {
    type: [Boolean, String],
    default: false,
  },
  codeText: {
    type: String,
    default: '获取验证码',
  },
  setTime: {
    type: [Number, String],
    default: 60,
  },
  focus: {
    type: [Boolean, String],
    default: false,
  },
})

const emit = defineEmits([
  'update:modelValue',
  'blur',
  'focus',
  'longpress',
  'confirm',
  'click',
  'longtap',
  'touchcancel',
  'touchend',
  'touchmove',
  'touchstart',
  'setCode',
])

const showPassword = ref(false)
const second = ref(0)
const isRunCode = ref(false)
let countDown: ReturnType<typeof setInterval> | null = null

const _type = computed(() => {
  return props.type === 'password' ? 'text' : props.type
})

const _isShowPass = computed(() => {
  return String(props.isShowPass) !== 'false'
})

const _isShowCode = computed(() => {
  return String(props.isShowCode) !== 'false'
})

const _setTime = computed(() => {
  const setTime = Number(props.setTime)
  return setTime > 0 ? setTime : 60
})

const _focus = computed(() => {
  return String(props.focus) !== 'false'
})

const getVerCodeSecond = computed(() => {
  if (second.value <= 0) {
    return props.codeText
  }
  else {
    return second.value < 10 ? `0${second.value}` : second.value
  }
})

function showPass() {
  showPassword.value = !showPassword.value
}

function setCode() {
  if (isRunCode.value)
    return
  emit('setCode')
}

function runCode(val: string | number) {
  if (String(val) === '0') {
    second.value = 0
    if (countDown)
      clearInterval(countDown)
    isRunCode.value = false
    return
  }

  if (isRunCode.value)
    return

  isRunCode.value = true
  second.value = _setTime.value

  countDown = setInterval(() => {
    second.value--
    if (second.value === 0) {
      isRunCode.value = false
      if (countDown)
        clearInterval(countDown)
    }
  }, 1000)
}

defineExpose({
  runCode,
})

onMounted(() => {
  if (countDown)
    clearInterval(countDown)
})
</script>

<template>
  <view class="main-list oBorder">
    <input
      class="main-input"
      :value="modelValue"
      :type="_type"
      :focus="_focus"
      :maxlength="maxlength"
      :placeholder="placeholder"
      :password="type === 'password' && !showPassword"

      @input="emit('update:modelValue', $event.detail.value)"
      @blur="emit('blur', $event)"
      @focus="emit('focus', $event)"
      @longpress="emit('longpress', $event)"
      @confirm="emit('confirm', $event)"
      @click="emit('click', $event)"
      @longtap="emit('longtap', $event)"
      @touchcancel="emit('touchcancel', $event)"
      @touchend="emit('touchend', $event)"
      @touchmove="emit('touchmove', $event)"
      @touchstart="emit('touchstart', $event)"
    >
    <image
      v-if="_isShowPass && type === 'password' && !_isShowCode"
      class="img cuIcon"
      :class="showPassword ? 'cuIcon-attention' : 'cuIcon-attentionforbid'"
      @tap="showPass"
    />
    <view
      v-if="_isShowCode && !_isShowPass"
      class="vercode" :class="[{ 'vercode-run': second > 0 }]"
      @click="setCode"
    >
      {{ getVerCodeSecond }}
    </view>
  </view>
</template>

<style scoped>
@import "./css/icon.css";

.main-list {
  display: flex;
  flex-direction: row;
  justify-content: space-between;
  align-items: center;
  color: #333333;
  padding: 40rpx 32rpx;
  margin: 32rpx 0;
}

.img {
  width: 32rpx;
  height: 32rpx;
  font-size: 32rpx;
}

.main-input {
  flex: 1;
  text-align: left;
  font-size: 28rpx;
  padding-right: 10rpx;
  margin-left: 20rpx;
}

.vercode {
  color: rgba(0, 0, 0, 0.7);
  font-size: 24rpx;
}

.vercode-run {
  color: rgba(0, 0, 0, 0.4) !important;
}

.oBorder {
  border: none;
  border-radius: 2.5rem;
  -webkit-box-shadow: 0 0 60rpx 0 rgba(43, 86, 112, .1);
  box-shadow: 0 0 60rpx 0 rgba(43, 86, 112, .1);
}
</style>
